
// Ez a kod a PIC18F4550-re mukodik, a 0.3-es GSR katyaval grafikus LCD
// 

// Szukseges: MPLAB IDE v8.83
//            Nem biztos: Microchip Solutions v2011-12-05
//            MPLAB C18

#ifndef MAIN_C
#define MAIN_C

/** INCLUDES *******************************************************/
#include <delays.h>
#include <stdio.h>

#include "p18cxxx.h"
#include "hardware.h"
#include "xlcd.h"
#include "stepper.h"
#include "pic_eeprom.h"
#include "dht11.h"
#include "mydelay.h"

/** CONFIGURATION **************************************************/
// Configuration bits for PICDEM FS USB Demo Board (based on PIC18F4550)
        #pragma config PLLDIV   = 5         // (20 MHz crystal on PICDEM FS USB board)
        #pragma config CPUDIV   = OSC1_PLL2   // Andras 24Mhz system clock
        //#pragma config CPUDIV   = OSC4_PLL6     // Andras 12
        #pragma config USBDIV   = 2         // Clock source from 96MHz PLL/2
        #pragma config FOSC     = HSPLL_HS // Andras eredeti
        //#pragma config FOSC     = HS
        #pragma config FCMEN    = OFF
        #pragma config IESO     = OFF
        #pragma config PWRT     = OFF
        #pragma config BOR      = ON
        #pragma config BORV     = 3
        #pragma config VREGEN   = ON      //USB Voltage Regulator
        #pragma config WDT      = OFF
        #pragma config WDTPS    = 32768
        #pragma config MCLRE    = ON
        #pragma config LPT1OSC  = OFF
        #pragma config PBADEN   = OFF
//      #pragma config CCP2MX   = ON
        #pragma config STVREN   = ON
        #pragma config LVP      = OFF
//      #pragma config ICPRT    = OFF       // Dedicated In-Circuit Debug/Programming
        #pragma config XINST    = OFF       // Extended Instruction Set
        #pragma config CP0      = OFF
        #pragma config CP1      = OFF
//      #pragma config CP2      = OFF
//      #pragma config CP3      = OFF
        #pragma config CPB      = OFF
//      #pragma config CPD      = OFF
        #pragma config WRT0     = OFF
        #pragma config WRT1     = OFF
//      #pragma config WRT2     = OFF
//      #pragma config WRT3     = OFF
        #pragma config WRTB     = OFF       // Boot Block Write Protection
        #pragma config WRTC     = OFF
//      #pragma config WRTD     = OFF
        #pragma config EBTR0    = OFF
        #pragma config EBTR1    = OFF
//      #pragma config EBTR2    = OFF
//      #pragma config EBTR3    = OFF
        #pragma config EBTRB    = OFF


#pragma romdata


/** VARIABLES ******************************************************/
#pragma udata

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////

unsigned char prescaler=2;
double dt = 1.0 / (12.0e6/ (2<<2) / 65536.0);

unsigned long msec=0;

unsigned char TOUT=0;

unsigned char D=0, H=0, M=0, S=0;

//unsigned long last_msec=0;
//unsigned long sw_on=0;

int n_inth=0; // number of high prio interrupts
int n_intl=0; // number of low prio interrupts

// speed in microsec between steps (motor speed)
#define SPEED 1000       
// when this is reached, go back to zero pos
#define MAXPOS 7000  
// how much to turn on each period 
#define DX 700         
// time between periods
#define DT 60000         

#pragma udata otherdata

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma code



void high_isr(void);


#pragma code high_vector=0x08
void interrupt_at_high_vector(void) {
   _asm GOTO high_isr _endasm
}



#pragma code

#pragma interrupt high_isr

void high_isr (void) {
   if (INTCONbits.TMR0IF){  // Interrupt Check   
      INTCONbits.TMR0IF = 0;                 
      //TMR0H = 0x85;        //Timer Reload to count 1s
      //TMR0L = 0xEE;                    
      //msec++;
      msec += (unsigned long)(dt*1000.0);

      S = (msec/1000) % 60;
      M = (msec/1000/60) % 60;
      H = (msec/1000/3600) % 24;
      D = msec/1000/3600/24 ;
   }

/*
   if(PIR1bits.TMR2IF){
      TOUT = 1;
      T2CONbits.TMR2ON = 0; // stop timer
      PIR1bits.TMR2IF  = 0; // Clear TMR0 interrupt flag
  }
*/
}

#pragma code





///////////////////////// ANDRIS ---- Delays for LCD module created by AppMaestro code generator
void XLCDDelay15ms (void)
{
    Delay_ms(15);
    return;
}

void XLCDDelay4ms (void)
{
    Delay_ms(4);
    return;
}
void XLCD_Delay500ns(void)
{
    Nop();
    Nop();
    Nop();
}
void XLCDDelay(void)
{
    int i;
    for(i=0;i<1000;i++)
        {
        Nop();
        }
    return;

}

unsigned char RH1, RH2, T1, T2;
unsigned char GetTemp(void) {
    unsigned char i, i1, i2, i3, i4, CS;

    DHTStartSignal();

    i=DHTCheckResponse();
    if(i>0) return i;
    
    i1 = ReadDHT();
    i2 = ReadDHT();
    i3 = ReadDHT();
    i4 = ReadDHT();
    CS = ReadDHT();

    if (CS != ((i1 + i2 + i3 + i4) & 0xFF)) {
       return 1;
    }

    RH1 = i1;
    RH2 = i2;
    T1 = i3;
    T2 = i4;

    return 0;
}


/********************************************************************
 *******************************************************************
*******************************************************************
*******************************************************************
*******************************************************************
*******************************************************************
*******************************************************************
*******************************************************************
*******************************************************************
 *******************************************************************/

void main(void)
{   
    unsigned char n, i, CS, TEMP=0, SET_TEMP=0, MOTOR=0;
    unsigned char e, check;
    unsigned char motor_init=1;
    char buf[20];

    long int motor_pos=0; // approximate position
    unsigned int motor_left=0;
    unsigned int motor_right=0;
    unsigned long last_motor=0;
    unsigned long last_lcd=0;

    // when any button is pressed, lemp goes on for 10 seconds
    // t_lamp is set to sec + 10s 
    unsigned long t_lamp=0;
    unsigned long t_pressed=0;
    unsigned long t_temp=0; // last time temp read

    ADCON1 |= 0x0F;                 // Default all pins to digital

    TRIS_RELAY = 0;
    TRIS_MICROSW = 1;
    TRIS_TEMP_INC = 1;
    TRIS_TEMP_DEC = 1;
   
    // make stepper motor pins output
    TRIS_S0=0;
    TRIS_S1=0;
    TRIS_S2=0;
    TRIS_S3=0;

    // TIMER0
    // enable timer0 and set scale down factor
    T0CON = prescaler; // prescaler
    TMR0H = 0; 
    TMR0L = 0; 
    T0CONbits.T0CS = 0; // internal clock
    T0CONbits.TMR0ON = 1; // enable interrupt
    INTCONbits.TMR0IE = 1; //enable 
    INTCONbits.TMR0IF = 0; // clear timer flag

    // Configure Timer2 module
    PIE1bits.TMR2IE = 1;  // Enable Timer2 interrupt
    T2CON = 0;        // Prescaler 1:1, and Timer2 is off initially
    PIR1bits.TMR2IF =0;   // Clear TMR INT Flag bit
    TMR2 = 0;


    // enable all interrupts
    RCONbits.IPEN=1;
    INTCONbits.GIEH=1;

    XLCDInit();  
    XLCDCommand(0b1100); // blink off, cursor off, display on

    // Check set temp and reset
    SET_TEMP = ReadPicEEPROM(0);
    if(SET_TEMP<10 || SET_TEMP>50) {
       SET_TEMP=35;
       WritePicEEPROM(0, SET_TEMP); 
    }

    MOTOR = ReadPicEEPROM(1);
    if(MOTOR>1) {
       MOTOR=1;
       WritePicEEPROM(1, MOTOR);
    }

    RELAY=0;

    // move to the initial position
    motor_init=1;

    i=0;
    while(1) {
       i++;

       if(msec - t_temp>10000) {
          
          e=GetTemp();
          t_temp = msec;

          //e=0;
          if(e==0) {
             TEMP = T1;
          }

          if(e!=0) {
             XLCDL1home();
             sprintf(buf, "ERROR %d %d  ", i, e);
             XLCDPutRamString(buf);
             //while(1);
             //TEMP=0;
             //RH1=0;
          }
       }


       if(msec-last_lcd>100) {
          last_lcd = msec;

          XLCDL1home();
          //if(msec%10000 < 5000) {
          //   sprintf(buf, "%2d:%02d:%02d:%02d ", D, H, M, S);
          //} else {
             sprintf(buf, "%d %d ", (int)(msec/1000), (int)motor_pos);
          //}
          XLCDPutRamString(buf);

          if(MOTOR) {
             if(msec%1000<500) XLCDPutRomString("    ");
             else XLCDPutRomString("M:BE");
          } else XLCDPutRomString("M:KI");

          XLCDL2home();
          sprintf(buf, "%2d%c %2d%% [%2d%c]", TEMP, 0b11011111, RH1, SET_TEMP, 0b11011111);
          XLCDPutRamString(buf);
       }

       if((msec < t_lamp) || (TEMP<SET_TEMP)) RELAY = 1;
       else RELAY = 0;

       // all switches are pulled up, so 0 means pressed
       if(TEMP_INC==0 && t_pressed==0) {
         t_pressed = msec;
         t_lamp = msec + 10000;
       }
       if(TEMP_DEC==0 && t_pressed==0) {
         t_pressed = msec;
         t_lamp = msec + 10000;
       }

       // if none are pressed
       if(TEMP_INC && TEMP_DEC) t_pressed = 0;       

       if(t_pressed>0 && msec - t_pressed > 1000) {
          t_pressed = 0;

          // both are pressed
          if((!TEMP_INC) && (!TEMP_DEC)) {
             MOTOR=1-MOTOR;
             if(MOTOR) {
                motor_left=0; motor_right=0; motor_init=1;
             }
             WritePicEEPROM(1, MOTOR);
          } else if(!TEMP_INC) {
             SET_TEMP++;
             WritePicEEPROM(0, SET_TEMP); 
          } else if(!TEMP_DEC) {
             SET_TEMP--;
             WritePicEEPROM(0, SET_TEMP);  
          }
       }

       // if motor is enabled
       if(MOTOR && msec - last_motor > DT && motor_init==0) {
          last_motor = msec;

          if(motor_pos<MAXPOS) {
             motor_right = DX;
          } else motor_init = 1;

       }

       if(motor_init && MOTOR) {
          // if reached init
          if(!MICROSW) {
             motor_init=0;
             motor_pos=0;
          } else {
             Left(SPEED);
             motor_pos--;
             last_motor=msec;
          }
       } else if(motor_left && MOTOR) {
          Left(SPEED);
          motor_left--;
          motor_pos --;
          last_motor = msec;
       } else if(motor_right && MOTOR) {
          Right(SPEED);
          motor_right--;
          motor_pos ++;
          last_motor = msec;
       } else {
          StepperOff();
       }
   }

}//end main




/** EOF main.c *************************************************/
#endif
